﻿using System.CodeDom;
using System.Collections.Generic;
using System.Linq;
using Library;
using Library.Models;
using Newtonsoft.Json;
using PagedList;

namespace Ecommerce.Models
{
    public class ProductViewModel
    {
        public ProductViewModel()
        {

        }
        public ProductViewModel(Product data)
        {
            Id = data.Id;
            PriceDisplay = data.PriceDisplay;
            StrikethroughPriceDisplay = data.StrikethroughPriceDisplay;
            Status = data.Status.HasValue ? (ProductStatuses)data.Status : ProductStatuses.Undefined;
            Brand = new BrandViewModel(data.Brand);
            ProductCultures = data.ProductCultures;

            ProductCategory = new ProductCategoryViewModel(data.ProductCategory, false);

            if (!string.IsNullOrEmpty(data.Specifications))
            {
                Specifications = JsonConvert.DeserializeObject<List<ProductSpecification>>(data.Specifications);

                var specificationGroups = data.ProductCategory.SpecificationGroups.OrderBy(i => i.DisplayOrder).ToDictionary(i => i.Id);

                var tempSpecs = new List<Specification>();
                var tempSpecValues = new List<SpecificationValue>();
                foreach (var specGroup in specificationGroups)
                {
                    tempSpecs.AddRange(specGroup.Value.Specifications.OrderBy(i => i.DisplayOrder));
                    foreach (var spec in specGroup.Value.Specifications)
                    {
                        tempSpecValues.AddRange(spec.SpecificationValues);
                    }
                }
                var specifications = tempSpecs.ToDictionary(i => i.Id);
                var specificationValues = tempSpecValues.ToDictionary(i => i.Id);

                SpecificationGroups = new List<SpecificationGroupView>();
                foreach (var ps in Specifications)
                {
                    SpecificationGroup specGroup;
                    if (specificationGroups.TryGetValue(ps.SpecificationGroupId, out specGroup))
                    {
                        Specification spec;
                        if (specifications.TryGetValue(ps.SpecificationId, out spec))
                        {
                            SpecificationValue specVal;
                            if (specificationValues.TryGetValue(ps.SpecificationValueId, out specVal))
                            {
                                var specGroupView = SpecificationGroups.SingleOrDefault(i => i.SpecificationGroup.Id == specGroup.Id);
                                if (specGroupView == null)
                                {
                                    SpecificationGroups.Add(new SpecificationGroupView
                                    {
                                        SpecificationGroup = new SpecificationGroup
                                        {
                                            Id = specGroup.Id,
                                            SpecificationGroupCultures = specGroup.SpecificationGroupCultures
                                        },
                                        Specifications = new Dictionary<Specification, SpecificationValue>(new SpecificationEqualityComparer()) {{new Specification
                                        {
                                            Id = spec.Id,
                                            SpecificationGroupId = spec.SpecificationGroupId,
                                            SpecificationCultures = spec.SpecificationCultures
                                        }, specVal}}
                                    });
                                }
                                else
                                {
                                    specGroupView.Specifications.Add(new Specification
                                    {
                                        Id = spec.Id,
                                        SpecificationGroupId = spec.SpecificationGroupId,
                                        SpecificationCultures = spec.SpecificationCultures
                                    }, specVal);
                                }
                            }
                        }
                    }
                }
            }
        }

        public ProductImage GetAvatar(string culture)
        {
            var gallery = GetGallery(culture);
            if (gallery != null)
            {
                return gallery.FirstOrDefault(i => i.IsAvatar.HasValue && i.IsAvatar.Value) ?? gallery.FirstOrDefault();
            }
            return null;
        }

        public List<ProductImage> GetGallery(string culture)
        {
            var productCulture = ProductCultures.SingleOrDefault(i => i.Culture == culture);
            if (productCulture != null && !string.IsNullOrEmpty(productCulture.Gallery))
            {
                return JsonConvert.DeserializeObject<List<ProductImage>>(productCulture.Gallery);
            }
            return null;
        }

        public string GetUrl(string culture)
        {
            var productCulture = ProductCultures.SingleOrDefault(i => i.Culture == culture);
            var productCategoryCulture = ProductCategory.ProductCategoryCultures.SingleOrDefault(i => i.Culture == culture);
            if (productCulture != null && productCategoryCulture != null)
            {
                return productCategoryCulture.Url + "/" + productCulture.Url;
            }
            return null;
        }

        public int Id { get; set; }
        public string PriceDisplay { get; set; }
        public string StrikethroughPriceDisplay { get; set; }
        public ProductStatuses Status { get; set; }
        public List<SpecificationGroupView> SpecificationGroups { get; set; }
        public List<ProductSpecification> Specifications { get; set; }
        public BrandViewModel Brand { get; set; }
        public ProductCategoryViewModel ProductCategory { get; set; }
        public ICollection<ProductCulture> ProductCultures { get; set; }

        public ProductImage Avatar
        {
            get { return GetAvatar(NOWCulture.CurrentCulture); }
        }

        public string Url
        {
            get { return GetUrl(NOWCulture.CurrentCulture); }
        }

        public class ProductSpecification
        {
            public int SpecificationGroupId;
            public int SpecificationId;
            public int SpecificationValueId;
        }

        public class SpecificationGroupView
        {
            public SpecificationGroup SpecificationGroup { get; set; }
            public Dictionary<Specification, SpecificationValue> Specifications { get; set; }
        }

        public class SpecificationEqualityComparer : IEqualityComparer<Specification>
        {
            public bool Equals(Specification x, Specification y)
            {
                return x.Id == y.Id;
            }

            public int GetHashCode(Specification obj)
            {
                return obj.Id;
            }
        }
    }

    public class ProductSpecificationsView
    {
        public ProductSpecificationsView(ICollection<SpecificationGroup> specificationGroups)
        {

        }
    }
}